namespace MicroCloud.CodeGenerator.Views
{
    public class ViewModelLocator
    {
        public static ViewModelLocator Instance => new Lazy<ViewModelLocator>(() =>
         Application.Current.TryFindResource("Locator") as ViewModelLocator).Value;

        /// <summary>
        /// 获取 实体主键类型数据源
        /// </summary>
        public string[] EntityKeys { get; } =
        {
            typeof(int).FullName,
            typeof(Guid).FullName,
            typeof(string).FullName,
            typeof(long).FullName
        };

        public string[] TypeNames { get; } =
        {
            typeof(string).FullName,
            typeof(Guid).FullName,
            typeof(DateTime).FullName,

            typeof(bool).FullName,
            typeof(byte).FullName,
            typeof(int).FullName,
            typeof(long).FullName,

            typeof(decimal).FullName,
            typeof(double).FullName,
            typeof(float).FullName,

            typeof(byte[]).FullName,
            typeof(object).FullName,
            "ICollection<>"
        };

        public ForeignRelation[] ForeignRelations { get; } =
        {
            ForeignRelation.OneToOne , ForeignRelation.OneToMany, ForeignRelation.ManyToOne
        };

        public DeleteBehavior?[] DeleteBehaviors { get; } =
        {
             null,DeleteBehavior.ClientSetNull,DeleteBehavior.Restrict,DeleteBehavior.SetNull,
            DeleteBehavior.Cascade, DeleteBehavior.ClientCascade, DeleteBehavior.NoAction, DeleteBehavior.ClientNoAction
        };

        public MetadataType[] MetadataTypes { get; } = { MetadataType.Entity, MetadataType.Module, MetadataType.Project };

        public string[] TemplateFiles { get; } = { "内置" };

        public string[] Entities => GetEntities();

        private CodeProject _project;
        private string[] GetEntities()
        {
            ProjectViewModel project = IoC.Get<MenuViewModel>().Project;
            ModuleListViewModel moduleList = IoC.Get<ModuleListViewModel>();
            List<string> list = new List<string>();
            //list.AddRange(new[]
            //{
            //    "Identity.Entities.LoginLog",
            //    "Identity.Entities.Organization",
            //    "Identity.Entities.Role",
            //    "Identity.Entities.RoleClaim",
            //    "Identity.Entities.User",
            //    "Identity.Entities.UserClaim",
            //    "Identity.Entities.UserDetail",
            //    "Identity.Entities.UserLogin",
            //    "Identity.Entities.UserRole",
            //    "Identity.Entities.UserToken",
            //}.Select(m => $"{project.NamespacePrefix}.{m}"));

            if (moduleList != null)
            {
                if (_project == null)
                {
                    IServiceProvider rootProvider = IoC.Get<IServiceProvider>();
                    MenuViewModel menu = rootProvider.GetRequiredService<MenuViewModel>();
                    rootProvider.ExecuteScopedWork(provider =>
                    {
                        IDataContract contract = provider.GetRequiredService<IDataContract>();
                        _project = contract.GetCodeProject(m => m.Name == menu.Project.Name).First();
                    });
                }
                list.AddRange(_project.Modules.SelectMany(m => m.Entities.Select(n => $"{project.NamespacePrefix}.{m.Name}.Entities.{n.Name}Entity"))
                    .OrderBy(m => m));
            }

            return list.Distinct().ToArray();
        }

        public void Refresh()
        {
            _project = null;
        }
    }
}
